# -*- coding: utf-8 -*-
import hashlib
import json
import os
import six
from collections import abc
from pkgutil import iter_modules
from importlib import import_module
from qcloud_cos import CosConfig, CosS3Client
from squirrel_core.commons.utils.get_config import get_config

BASE_CONFIG_FROM_CONF = get_config(sections="base")


def upload_file(local_file, cos_path):
    i = 0
    while i < 3:
        secret_id = BASE_CONFIG_FROM_CONF.get("secret_id", "")
        region = BASE_CONFIG_FROM_CONF.get("region", "")
        secret_key = BASE_CONFIG_FROM_CONF.get("secret_key", "")
        bucket_name = BASE_CONFIG_FROM_CONF.get("bucket_name", "")
        config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key)
        client = CosS3Client(config)
        try:
            client.upload_file(
                Bucket=bucket_name,
                LocalFilePath=local_file,
                Key=cos_path
            )
            print(f"文件上传成功！")
            try:
                os.remove(local_file)
            except Exception:
                pass
            return True
        except Exception as e:
            i += 1
            print(f"上传失败: {str(e)}")
    return False


def convert_dict2str(target_value):
    """
    convert dict to string with order
    Args:
    Returns:
        a string value
    """
    if isinstance(target_value, abc.MutableMapping):
        rtn = ""
        for key, value in sorted(target_value.items(), key=lambda item: item[0], reverse=False):
            rtn = "".join([rtn, convert_dict2str(key), "=", convert_dict2str(value), "|"])
        return rtn
    elif isinstance(target_value, str):
        return target_value
    elif target_value is None:
        return ""
    else:
        return str(target_value)


def calc_str_md5(strings):
    """
    calculate str md5
    :param strings: 
    :return: 
    """
    md5_obj = hashlib.md5()
    md5_obj.update(strings.encode())
    md5_str = md5_obj.hexdigest()
    return md5_str


def gen_rowkey(item, keys=('do_time', 'name_second')):
    item_dict = dict(item)
    item_dict.pop('uptime', '')
    md5str = calc_str_md5(json.dumps(item_dict, ensure_ascii=False))
    rowkey_list = [md5str]
    rowkey_list.extend([item_dict.get(x) for x in keys])
    rowkey = '|_|'.join(rowkey_list)
    return rowkey


def patch_global_logger(logger):
    from logging import Logger
    import sys
    try:
        for module_name, _module in sys.modules.items():
            try:
                if hasattr(_module, 'logger') and isinstance(_module.logger, Logger):
                    setattr(_module, 'logger', logger)
            except:
                pass
    except Exception as e:
        pass


def str_to_bool(value):
    if isinstance(value, bool):
        return value
    elif isinstance(value, str):
        if value.lower() in ['false', '']:
            return False
        else:
            return True
    else:
        raise TypeError('value must be string or bool')
    

def str_to_int(value):
    if isinstance(value, (int, float, str, bytes)):
        return int(value)
    else:
        raise TypeError('Value must be int, float, str or bytes')
    

def get_business_key_name(name_first, name_second):
    return "{}_{}".format(name_first, name_second)


def set_log_env(name_first, name_second, log_name='spider', job_id=None, log_root_folder=None):
    os.environ.setdefault('NAME_FIRST', name_first)
    os.environ.setdefault('NAME_SECOND', name_second)
    if not log_root_folder:
        log_root_folder = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    os.environ.setdefault('LOG_ROOT_FOLD', log_root_folder)
    os.environ.setdefault('LOG_NAME', log_name)
    if job_id:
        os.environ.setdefault('JOB_ID', str(job_id))


def bytes_to_str(s, encoding='utf-8'):
    if six.PY3 and isinstance(s, bytes):
        return s.decode(encoding)
    return s


def walk_modules(path):
    mods = []
    try:
        mod = import_module(path)
    except Exception:
        return mods
    mods.append(mod)
    if hasattr(mod, '__path__'):
        for _, subpath, ispkg in iter_modules(mod.__path__):
            fullpath = path + '.' + subpath
            if ispkg:
                mods += walk_modules(fullpath)
            else:
                try:
                    submod = import_module(fullpath)
                except Exception:
                    continue
                else:
                    mods.append(submod)
    return mods


def key_business_param_from_settings(settings):
    return {'name_first': settings.get('NAME_FIRST'), 'name_second':settings.get('NAME_SECOND')}


if __name__ == '__main__':
    pass
